package jbrowser.gui;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import jbrowser.gui.history.HistoryManager;
import jbrowser.gui.history.History;
import jbrowser.api.SessionStore;

public class Tab extends JPanel implements ActionListener {

    private static final Logger logger = Logger.getLogger(Tab.class.getName());
    private Window window;
    private ImageIcon iconCacheOn;
    private ImageIcon iconCacheOff;
    private Page currentPage;
    private URI currentURI;
    private History<URI> history = new History<URI>();
    private Map<URI, Page> pageCache = new HashMap<URI, Page>();
    private SessionStore sessionStore;// = new SessionStore();

    public Tab(Window window) {
        this.window = window;
        initComponents();

        iconCacheOff = new ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/cache_off.png"));
        iconCacheOn = new ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/cache_on.png"));

        cmbAddress.addActionListener(this);
        btnRefresh.addActionListener(this);
        btnClose.addActionListener(this);
        btnHome.addActionListener(this);
        btnOpen.addActionListener(this);
        tbtHold.addActionListener(this);
        HistoryManager.manage(history, cmbAddress, btnBack, btnNext);
        //boolean showToolbarButtonText = JBrowser.getProperties().getProperty("window.toolbar.mode").contains("text");
        boolean showToolbarButtonText = false;
        if (!showToolbarButtonText) {
            for (Component c : tlbMain.getComponents()) {
                if (c instanceof JButton) {
                    ((JButton) c).setText(null);
                    ((JButton) c).setPreferredSize(new Dimension(36, 36));
                }
            }
        }
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                //cmbAddress.getEditor().setItem(URI.create(JBrowser.getProperties().getProperty("window.new_page")));
                cmbAddress.getEditor().setItem(URI.create(EmptyPage.class.getName()));
                cmbAddress.actionPerformed(null);
            }
        });
    }

    public History<URI> getHistory() {
        return history;
    }

    public Component getTabComponent() {
        return tabComponent;
    }

    void setIcon(Icon icon) {
        lblTabTitle.setIcon(icon);
    }

    void setTitle(String title) {
        int titleWidth = lblTabTitle.getGraphics().getFontMetrics().stringWidth(title);
        tabComponent.setPreferredSize(new Dimension(titleWidth + 46, 20));
        lblTabTitle.setText(title);
        window.setTitle(title + " - JBrowser");
    }

    String getTitle() {
        return lblTabTitle.getText();
    }

    public void setCacheMode(Page.CacheMode cacheMode) {
        tbtHold.setEnabled(!cacheMode.equals(Page.CacheMode.NEVER) && !cacheMode.equals(Page.CacheMode.REQUIRED));
        tbtHold.setSelected(cacheMode.equals(Page.CacheMode.SUPPORTS) || cacheMode.equals(Page.CacheMode.REQUIRED));
    }

    public void setStatus(String message) {
        lblStatus.setText(message);
    }

    public void close() {
        this.removeAll();
        // Ha ez az utolsó tab, akkor az előző legyen az aktív, ne a következő
        JTabbedPane jTabbedPane = (JTabbedPane) this.getParent();
        int myIndex = jTabbedPane.indexOfComponent(this);
        if (myIndex > 0 && myIndex == jTabbedPane.getTabCount() - 2) {
            jTabbedPane.setSelectedIndex(myIndex - 1);
        }
        jTabbedPane.remove(this);
    }

    public final void setPage(Page page) {
        currentPage = page;
        this.add(page.getComponent(), java.awt.BorderLayout.CENTER);
        setTitle(page.getTitle());
        setIcon(page.getIcon());
        setCacheMode(page.getCacheMode());
        this.validate();
        this.repaint();
    }

    public void newPage(final URI uri) {
        logger.log(Level.INFO, "newPage({0})", uri);
        try {
            if (currentPage != null) {
                this.remove(currentPage.getComponent());
                if (tbtHold.isSelected()) {
                    pageCache.put(currentURI, currentPage);
                } else {
                    pageCache.remove(currentURI);
                }
            }
            currentURI = uri;
            if (pageCache.containsKey(uri)) {
                lblCache.setIcon(iconCacheOn);
                setPage(pageCache.get(uri));
            } else {
                lblCache.setIcon(iconCacheOff);
                setPage(new ProxyPage(this, uri));
            }
        } catch (Exception ex) {
            logger.log(Level.SEVERE, null, ex);
            setPage(new ErrorPage(ex));
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if ("HOLD".equals(e.getActionCommand())) {
            //currentPage.setCacheMode(tbtHold.isSelected() ? Page.CacheMode.SUPPORTS : Page.CacheMode.NOT_SUPPORTED);
        } else if ("REFRESH".equals(e.getActionCommand())) {
            tbtHold.setSelected(false);
            pageCache.remove(currentURI);
            sessionStore.remove(sessionStore.getSession(currentURI));
            newPage(URI.create(cmbAddress.getSelectedItem().toString()));
        } else if ("ADDRESS".equals(e.getActionCommand())) {
            newPage(URI.create(cmbAddress.getSelectedItem().toString()));
        } else if ("HOME_PAGE".equals(e.getActionCommand())) {
            //cmbAddress.getEditor().setItem(URI.create(JBrowser.getProperties().getProperty("window.new_page")));
            cmbAddress.getEditor().setItem(URI.create(EmptyPage.class.getName()));
            cmbAddress.actionPerformed(null);
        } else if ("CLOSE_TAB".equals(e.getActionCommand())) {
            close();
        } else if ("OPEN_FILE".equals(e.getActionCommand())) {
            if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
                cmbAddress.getEditor().setItem(fileChooser.getSelectedFile().toURI());
                cmbAddress.actionPerformed(null);
            }
        } else if (e.getActionCommand() != null && !e.getActionCommand().isEmpty() && !e.getActionCommand().equals("comboBoxEdited")) {
            cmbAddress.getEditor().setItem(URI.create(e.getActionCommand()));
            cmbAddress.actionPerformed(null);
        }
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        tabComponent = new javax.swing.JPanel();
        lblTabTitle = new javax.swing.JLabel();
        btnClose = new javax.swing.JButton();
        fileChooser = new javax.swing.JFileChooser();
        tlbMain = new javax.swing.JToolBar();
        btnOpen = new javax.swing.JButton();
        btnBack = new javax.swing.JButton();
        btnNext = new javax.swing.JButton();
        btnHome = new javax.swing.JButton();
        cmbAddress = new javax.swing.JComboBox();
        btnRefresh = new javax.swing.JButton();
        tlbFoot = new javax.swing.JToolBar();
        lblCache = new javax.swing.JLabel();
        tbtHold = new javax.swing.JToggleButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        lblStatus = new javax.swing.JLabel();
        jSeparator2 = new javax.swing.JToolBar.Separator();

        tabComponent.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 1, 1, 1));
        tabComponent.setFocusable(false);
        tabComponent.setMaximumSize(new java.awt.Dimension(512, 20));
        tabComponent.setMinimumSize(new java.awt.Dimension(96, 20));
        tabComponent.setOpaque(false);
        tabComponent.setPreferredSize(new java.awt.Dimension(96, 20));
        tabComponent.setLayout(new java.awt.GridBagLayout());

        lblTabTitle.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/page.png"))); // NOI18N
        lblTabTitle.setText("New Tab");
        lblTabTitle.setFocusable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        tabComponent.add(lblTabTitle, gridBagConstraints);

        btnClose.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/closeTabButtonGray.png"))); // NOI18N
        btnClose.setToolTipText("Close Tab");
        btnClose.setActionCommand("CLOSE_TAB");
        btnClose.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        btnClose.setBorderPainted(false);
        btnClose.setContentAreaFilled(false);
        btnClose.setFocusable(false);
        btnClose.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnClose.setMaximumSize(new java.awt.Dimension(16, 16));
        btnClose.setMinimumSize(new java.awt.Dimension(16, 16));
        btnClose.setPreferredSize(new java.awt.Dimension(16, 16));
        btnClose.setPressedIcon(new javax.swing.ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/closeTabButton.png"))); // NOI18N
        btnClose.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/closeTabButton.png"))); // NOI18N
        btnClose.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.weighty = 0.1;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        tabComponent.add(btnClose, gridBagConstraints);

        setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 2, 2, 2));
        setLayout(new java.awt.BorderLayout(2, 2));

        tlbMain.setFloatable(false);
        tlbMain.setRollover(true);

        btnOpen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/open.png"))); // NOI18N
        btnOpen.setText("Open");
        btnOpen.setActionCommand("OPEN_FILE");
        btnOpen.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        btnOpen.setFocusable(false);
        btnOpen.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnOpen.setMaximumSize(new java.awt.Dimension(64, 64));
        btnOpen.setMinimumSize(new java.awt.Dimension(24, 24));
        btnOpen.setOpaque(false);
        btnOpen.setPreferredSize(new java.awt.Dimension(64, 64));
        btnOpen.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        tlbMain.add(btnOpen);

        btnBack.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/back.png"))); // NOI18N
        btnBack.setText("Back");
        btnBack.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        btnBack.setEnabled(false);
        btnBack.setFocusable(false);
        btnBack.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnBack.setMaximumSize(new java.awt.Dimension(64, 64));
        btnBack.setMinimumSize(new java.awt.Dimension(24, 24));
        btnBack.setOpaque(false);
        btnBack.setPreferredSize(new java.awt.Dimension(64, 64));
        btnBack.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        tlbMain.add(btnBack);

        btnNext.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/forward.png"))); // NOI18N
        btnNext.setText("Next");
        btnNext.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        btnNext.setEnabled(false);
        btnNext.setFocusable(false);
        btnNext.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnNext.setMaximumSize(new java.awt.Dimension(64, 64));
        btnNext.setMinimumSize(new java.awt.Dimension(24, 24));
        btnNext.setOpaque(false);
        btnNext.setPreferredSize(new java.awt.Dimension(64, 64));
        btnNext.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        tlbMain.add(btnNext);

        btnHome.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/home.png"))); // NOI18N
        btnHome.setText("Home");
        btnHome.setActionCommand("HOME_PAGE");
        btnHome.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        btnHome.setFocusable(false);
        btnHome.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnHome.setMaximumSize(new java.awt.Dimension(64, 64));
        btnHome.setMinimumSize(new java.awt.Dimension(24, 24));
        btnHome.setOpaque(false);
        btnHome.setPreferredSize(new java.awt.Dimension(64, 64));
        btnHome.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        tlbMain.add(btnHome);

        cmbAddress.setEditable(true);
        cmbAddress.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "mvn://pacman:pacman-srv", "mvn://certman:certman-srv", "mvn://pacman:pacman-srv:1.0-SNAPSHOT", "mvn://certman:certman-srv:1.0-SNAPSHOT", "jbrowser.gui.settings.SettingsPage" }));
        cmbAddress.setActionCommand("ADDRESS");
        cmbAddress.setMaximumSize(new java.awt.Dimension(4096, 22));
        cmbAddress.setMinimumSize(new java.awt.Dimension(128, 22));
        cmbAddress.setPreferredSize(new java.awt.Dimension(512, 22));
        tlbMain.add(cmbAddress);

        btnRefresh.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/refresh.png"))); // NOI18N
        btnRefresh.setText("Refresh");
        btnRefresh.setActionCommand("REFRESH");
        btnRefresh.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        btnRefresh.setFocusable(false);
        btnRefresh.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnRefresh.setMaximumSize(new java.awt.Dimension(64, 64));
        btnRefresh.setMinimumSize(new java.awt.Dimension(24, 24));
        btnRefresh.setOpaque(false);
        btnRefresh.setPreferredSize(new java.awt.Dimension(64, 64));
        btnRefresh.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        tlbMain.add(btnRefresh);

        add(tlbMain, java.awt.BorderLayout.NORTH);

        tlbFoot.setFloatable(false);
        tlbFoot.setRollover(true);
        tlbFoot.setMaximumSize(new java.awt.Dimension(32807, 24));
        tlbFoot.setMinimumSize(new java.awt.Dimension(50, 24));
        tlbFoot.setPreferredSize(new java.awt.Dimension(100, 24));

        lblCache.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblCache.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jsystem/jbrowser/resource/cache_off.png"))); // NOI18N
        tlbFoot.add(lblCache);

        tbtHold.setSelected(true);
        tbtHold.setText("Hold");
        tbtHold.setActionCommand("HOLD");
        tbtHold.setFocusable(false);
        tbtHold.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        tbtHold.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        tlbFoot.add(tbtHold);
        tlbFoot.add(jSeparator1);

        lblStatus.setText("Ready");
        tlbFoot.add(lblStatus);
        tlbFoot.add(jSeparator2);

        add(tlbFoot, java.awt.BorderLayout.SOUTH);
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnBack;
    private javax.swing.JButton btnClose;
    private javax.swing.JButton btnHome;
    private javax.swing.JButton btnNext;
    private javax.swing.JButton btnOpen;
    private javax.swing.JButton btnRefresh;
    private javax.swing.JComboBox cmbAddress;
    private javax.swing.JFileChooser fileChooser;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JLabel lblCache;
    private javax.swing.JLabel lblStatus;
    private javax.swing.JLabel lblTabTitle;
    private javax.swing.JPanel tabComponent;
    private javax.swing.JToggleButton tbtHold;
    private javax.swing.JToolBar tlbFoot;
    private javax.swing.JToolBar tlbMain;
    // End of variables declaration//GEN-END:variables
}